package oop.ex1.processToolKit;

import java.util.Iterator;

import oop.ex1.dataStructures.*;

public class ProcessManager {

	private ArrayPriorityQueue _processQueue;

	/**
	 * Process Manager Constructor
	 */
	public ProcessManager() {
		_processQueue = new ArrayPriorityQueue();
	}

	@SuppressWarnings("unchecked")
	public void addProcessTree(Process process) {
		_processQueue.push(process);
		for(Iterator processIterator = process.iterateSubProcesses();processIterator.hasNext();) {
			Process processtoInsert = (Process)processIterator.next();
			if(processtoInsert!=null) {
				addProcessTree(processtoInsert);
			}
		}
	}

	@SuppressWarnings("unchecked")
	private void updatePriority(Process process, int priority,ComparableObject referralObject)  throws ObjectNotFoundException {
		if(_processQueue.isObjectInQueue(process)) {
			
			if(process.getPriority()>priority && (Process)referralObject!=process.getParent()) {
				if(process.getParent()!=null) {
					updatePriority(process.getParent(), priority, process);
				}
				process.setPriority(priority);
				_processQueue.maxheapify_object(process);
			}
			if(process.getPriority()<priority) {
				for (Iterator it1 = process.iterateSubProcesses(); it1.hasNext();){
					updatePriority((Process)it1.next(), priority, process);
				}
				process.setPriority(priority);
				_processQueue.increase_object(process);
			}
			
		} else {
			throw new ObjectNotFoundException();
		}
	}
	
	
	public void updatePriority(Process process, int priority) throws ObjectNotFoundException {
		updatePriority(process,priority,null);
	}

	
	public void runAllProcesses() throws DisorderException {
		try {
			while(_processQueue.peek()!=null) {
				Process polledProcess=(Process)_processQueue.poll();
				if(polledProcess.getParent()!=null) {
					if(polledProcess.getParent().isTerminated()) {
						throw new DisorderException();
					}
				}
				polledProcess.run();
			}
		} catch (EmptyQueueException e) {
			// The queue is Empty. We should not do anything in this error.
		}
	}

}
